#ifndef __THREAD_HPP__
#define __THREAD_HPP__
#include<vector>
#include<iostream>
#include<string>
#include<functional>
#include<pthread.h>
#include<unistd.h>

namespace ThreadModule
{
    //给 函数参数为T（T为任意类型）的引用，返回值为 void 的函数 重命名为func_t
    template<typename T>
    using func_t=std::function<void(T&)>;

    template<typename T>
    class Thread
    {
    public:
        //线程的任务
        void Excute()
        {
            _func(_data);
        }
    public:
        //构造函数
        Thread(func_t<T> func, T &data,const std::string &name="none-name")
            :_func(func),_data(data),_threadname(name),_stop(true)
        {  }

        //如果没有static，由于 this 指针，函数的参数有2个，而pthread_create要求函数参数只能有void*
        //加上static，则要求函数不能访问类内的非静态成员变量，也就避免了this指针作为函数参数        
        static void* threadroute(void* args)
        {
            //参数从void* 类型转为Thread<T> *类型，static_cast是一种相对安全的类型转换方式
            Thread<T> *self=static_cast<Thread<T> *>(args);

            //由于没有了this指针，所以需要封装Excute函数来传递 _data参数，从而执行任务
            self->Excute();
            return nullptr;
        }
        //开始执行任务
        bool Start()
        {
            //创建线程
            int n=pthread_create(&_tid,nullptr,threadroute,this);
            if(!n)
            {              
                _stop=false;//修改状态
                return true;
            }
            else
            {
                return false;
            }
        }
        void Detach()
        {
            //有线程启动了才分离线程
            if(!_stop)
                pthread_detach(_tid);
        }
        void Join()
        {
            if(!_stop)
                pthread_join(_tid,nullptr);
        }
        std::string name()
        {
            return _threadname;
        }
        void Stop()
        {
            _stop=true;
        }
        //析构函数
        ~Thread()
        {  }
    private:
        std::string _threadname;//线程名
        bool _stop;//该线程是否启动，true表示未启动，false表示已启动
        pthread_t _tid;
        T _data;
        func_t<T> _func;//线程调用的函数
    };
}
#endif